package com.jstyle.jclife.activity;

import android.Manifest;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.jstyle.blesdk.Util.SingleDealData;
import com.jstyle.blesdk.cmdenum.SendCmdState;
import com.jstyle.jclife.NetWork.NetWorkException;
import com.jstyle.jclife.NetWork.NetWorkUtil;
import com.jstyle.jclife.R;
import com.jstyle.jclife.app.MyApplication;
import com.jstyle.jclife.ble.BleManager;
import com.jstyle.jclife.model.BleData;

import com.jstyle.jclife.model.Device1810;
import com.jstyle.jclife.utils.DfuUtil;
import com.jstyle.jclife.utils.ImageUtils;
import com.jstyle.jclife.utils.PermissionsUtil;
import com.jstyle.jclife.utils.RxBus;
import com.jstyle.jclife.utils.SharedPreferenceUtils;
import com.jstyle.jclife.utils.Utils;
import com.jstyle.jclife.utils.ZipUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;


/**
 * Created by Administrator on 2018/12/5.
 */

public class FileUpdateActivity extends AppCompatActivity implements PermissionsUtil.PermissionListener {
    @BindView(R.id.iv_fileupdate_off)
    ImageView ivFileupdateOff;
    @BindView(R.id.iv_fileupdate_bg)
    ImageView ivFileupdateBg;
    @BindView(R.id.tv_find_new_version)
    TextView tvFindNewVersion;
    @BindView(R.id.tv_update_version)
    TextView tvUpdateVersion;
    @BindView(R.id.bt_update)
    Button btUpdate;
    @BindView(R.id.bt_update_cancel)
    Button btUpdateCancel;
    String version;
    String updateFilePath;
    protected Toast toast;
    public static final String key_version = "key_version";
    public static final String key_url = "key_url";
    public static final String key_battery = "key_battery";
    private ProgressDialog progressDialog;
    public static final String action_dfu_later = "dfu_later";
    private String otaPath;
    int battery;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_whether_update);
        ButterKnife.bind(this);
        version = getIntent().getStringExtra(key_version);
        updateFilePath = getIntent().getStringExtra(key_url);
        battery = getIntent().getIntExtra(key_battery, 0);
        init();
    }

    Disposable disposable;

    private void init() {
        if (!TextUtils.isEmpty(version))
            tvUpdateVersion.setText("V" + version);
        RxBus.getInstance().toObservable(BleData.class).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<BleData>() {
            @Override
            public void onSubscribe(Disposable d) {
                disposable = d;
            }

            @Override
            public void onNext(BleData bleData) {
                String action = bleData.getAction();
                if (BindDeviceListActivity.ActionDeviceChange.equals(action)) {
                    finish();
                }
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });
    }

    @OnClick({R.id.bt_update, R.id.iv_fileupdate_off, R.id.bt_update_cancel})
    public void onViewClicked(View view) {
        if (Utils.isFastClick()) {
            return;
        }
        switch (view.getId()) {
            case R.id.iv_fileupdate_off:
                sendAction();
                finish();
                break;
            case R.id.bt_update:
                if (battery < 20) {
                    showToast(getString(R.string.low_battery));
                } else {
                    PermissionsUtil.requestPermissions(this, this, Manifest.permission.WRITE_EXTERNAL_STORAGE);

                }
                break;
            case R.id.bt_update_cancel:
                sendAction();
                finish();
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unSubscribe(disposable);
        unSubscribe(downloadDisposable);
    }

    protected void unSubscribe(Disposable subscription) {
        if (subscription != null && !subscription.isDisposed()) {
            subscription.dispose();
        }
    }

    @Override
    public void granted(String name) {
        if (name.equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            startDownLoad();
        }
    }

    @Override
    public void NeverAskAgain() {
        finish();
    }

    @Override
    public void disallow(String name) {

    }

    public interface FileUpdateListener {
        public void startUpdateFile();

        public void laterUpdateFile();
    }

    private String updateFileName = "firmware.zip";
    private static final String TAG = "FileUpdateActivity";
    private Disposable downloadDisposable;

    private void startDownLoad() {
        String[] filePaths = updateFilePath.split("/");
        final String lastPath = filePaths[filePaths.length - 1];
        showProgressDialog(getString(R.string.Downloading_the_new_firmware));
        NetWorkUtil.getInstance().getJstyleApi().downloadPath(updateFilePath).
                subscribeOn(Schedulers.io()).observeOn(Schedulers.io())
                .doOnNext(new Consumer<ResponseBody>() {
                    @Override
                    public void accept(ResponseBody responseBody) throws Exception {

                        try {
                            writeToDisk(lastPath, responseBody);
                        } catch (IOException e) {
                            throw new NetWorkException(e.getMessage());
                        }
                    }
                }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<ResponseBody>() {
            @Override
            public void onSubscribe(Disposable d) {
                downloadDisposable = d;
            }

            @Override
            public void onNext(ResponseBody value) {


            }

            @Override
            public void onError(Throwable e) {
                disMissProgressDialog();
                Log.i(TAG, "onError: " + e.getMessage());
            }

            @Override
            public void onComplete() {
                Log.i(TAG, "onComplete: download");
                disMissProgressDialog();
                if (MyApplication.getJstyleDevice() instanceof Device1810) {
                    startDfu(ImageUtils.UPDATEPATH + File.separator + lastPath, false);
                    SharedPreferenceUtils.setSpString(SharedPreferenceUtils.KEY_RES_FILEPATH, ImageUtils.UPDATEPATH + File.separator + lastPath);
                } else {
                    String[] pathArray = lastPath.split("_");
                    String otaPathString = ImageUtils.UPDATEPATH + pathArray[1] + File.separator;
                    SharedPreferenceUtils.setSpString(SharedPreferenceUtils.KEY_RES_FILEPATH, otaPathString);
                    ZipUtils.upZipFile(ImageUtils.UPDATEPATH + lastPath, otaPathString);
                    otaPath = otaPathString + updateFileName;
                    startDfu(otaPath, false);
                }

            }
        });
    }

    public void showProgressDialog(String message) {
        if (isDestroyed()) return;
        if (progressDialog == null) {
            progressDialog = new ProgressDialog(this, R.style.appprogressdialog);
        }
        if (progressDialog.isShowing()) return;
        progressDialog.setMessage(message);
        progressDialog.show();
    }

    protected void disMissProgressDialog() {
        if (isDestroyed()) return;
        if (progressDialog != null && progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }

    private void startDfu(String lastPath, boolean repeat) {
        if (BleManager.getInstance().isConnected()) {
            BleManager.getInstance().writeValue(SingleDealData.sendData(SendCmdState.Enter_DfuMode));
        }
        DfuUtil.startDfuAndFinish(this, lastPath, version);

    }

    private void writeToDisk(final String filePath, ResponseBody responseBody) throws IOException {
        File file = new File(ImageUtils.UPDATEPATH);
        File fileMusic = new File(ImageUtils.UPDATEPATH + filePath);
        if (!file.exists()) {
            file.mkdirs();
        }
        if (fileMusic.exists() && fileMusic.length() == responseBody.contentLength()) return;
        byte[] buffer = new byte[1024 * 8];
        int len;
        FileOutputStream out = new FileOutputStream(fileMusic);
        InputStream in = responseBody.byteStream();
        while ((len = in.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        out.flush();
        out.close();
        in.close();


    }


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            return false;
        }
        return super.onKeyDown(keyCode, event);
    }


    private void sendAction() {
        RxBus rxBus = RxBus.getInstance();
        BleData bleData = new BleData();
        bleData.setAction(action_dfu_later);
        rxBus.post(bleData);
    }

    protected void showToast(String text) {
        if (toast == null) {
            toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT);
        } else {
            toast.setText(text);
        }
        toast.show();
    }
}
